/*********************************************************************************
 *      Copyright:  (C) 2022 zengwen<1825984037@qq.com>
 *                  All rights reserved.
 *
 *       Filename:  client_main.c
 *    Description:  This file 
 *                 
 *        Version:  1.0.0(07/07/22)
 *         Author:  zengwen <1825984037@qq.com>
 *      ChangeLog:  1, Release initial version on "07/07/22 15:29:42"
 *                 
 ********************************************************************************/
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h> 
#include <sys/socket.h>
#include <sys/stat.h>
#include <netinet/tcp.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <time.h>
#include <signal.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <getopt.h>
#include <libgen.h> 

#include "logger.h"
#include "sqlite3.h"
#include "database.h"
#include "get_massage.h"
#include "socket_client_init.h"
#include "send_data.h"

int judgment_time(int interval,time_t *last_time);
void sig_handle(int signum);
void print_usage(char *progname);

int get_stop=0;

int main (int argc, char **argv)
{
	char                 tpid[128];
	int                  rv;
	int                  ch;
	int                  port=0;
	char                 *ip = NULL;
	int                  daemon_run=0;
	char                 Data[256];
	char                 Buf[256];
	char                 massage[256];
	int                  sockfd=-1;
	struct sockaddr_in   sockaddr;
	int                  interval;
	time_t               last_time;
	char                 cur_time[64];
	char                 data;
	char                *progname=NULL;
	sqlite3             *db;
	struct tcp_info      info;
	int                  flag=0;
	int                  len=sizeof(info);
	struct option        opts[]={
		{"port",required_argument,NULL,'p'},
		{"ip",required_argument,NULL,'i'},
		{"time",required_argument,NULL,'t'},
		{"hlep",no_argument,NULL,'h'},
		{NULL,0,NULL,0}
	};

	progname = basename(argv[0]);

	while((ch=getopt_long(argc,argv,"p:i:t:h",opts,NULL))!=-1)
	{
		switch(ch)
		{
			case 'p':
				port=atoi(optarg);
				break;
			case 'i':
				ip=(optarg);
				break;
			case 't':
				interval=atoi(optarg);
				 break;
			case 'h':
				 print_usage(argv[0]);
				 return 0;
			default:
				 break;
		}
	}

	if(!port||!ip||!time)
	{
		print_usage(progname);
		return 0;
	}

	//信号捕捉
	/*
	signal(SIGINT, sig_handle);
	signal(SIGALRM, sig_handle);
	signal(SIGTERM, sig_handle);*/

	//日志
	rv= logger_init("/home/zengwen/client.log", LOG_LEVEL_MAX, 1024);
	if(rv < 0)
	{
		fprintf(stderr,"initial logger failure:%s\n",strerror(errno));
		return -1;
	}
	log_info("Logger system initialise ok\n");

	if(open_data_sqlite(&db))
	{
		log_warn("open database failure:%s\n",strerror(errno));
		return -2;
	}
	log_info("open database succesfully!\n");

	sockfd=socket_client_init(ip,port);

	while(1)
	{
		//采样
		time(&last_time);
		printf ("last_time=%d\n",last_time);
		rv=get_temper_ID (tpid );
		if(rv<0)
		{
			log_err("get temperature and pie_ID failure,rv=:%d\n",rv);
			return -1;
		}
	    log_info("tpid=%s\n",tpid);
		
		memset(Data,0,sizeof(Data));
		get_time(cur_time);
		printf("Now time Data is %sC\n",Data);
		flag=1;

		while(!(judgment_time(interval,&last_time)) )//未到采样时间 
		{
			getsockopt(sockfd, IPPROTO_TCP, TCP_INFO, &info, (socklen_t *)&len);//监听客户端状态，判断客户端是否已经连接服务器
			if(info.tcpi_state == TCP_ESTABLISHED)//客户端已连接服务器
			{
				if(flag==1)
				{
					if(socket_client_write(sockfd,Data)<0)//发送数据失败
					{
						printf("send realtime data failure:%s\n",strerror(errno));

						if(save_data_sqlite(db,Data)<0)//保存到数据库
						{
							log_err("insert data failure:%s\n",strerror(errno));
						}
						log_info("sava data to database succesfully\n");
					}
					flag=0;
				}
				printf ("Realtime data have sent. \n");

				memset(Buf,0,sizeof(Buf));
				if(get_data_sqlite(db,Buf)==0)//读取数据库保存的数据成功
				{
					if(strlen(Buf) != 0)//数据库不为空
					{
						printf("数据库获取的数据：%s\n",Buf);

						if(0==socket_client_write(sockfd,Buf))//发送数据
						{
							log_info("send data from database succesfully\n");

							if(delete_data_sqlite(db)<0)
							{
								log_err("delete data from databases failure:%s\n",strerror(errno));
							}
							log_info("delete data from database successfully\n");
						
						}
						else//发送数据失败
						{
							printf("send data from database failure:%s\n",strerror(errno));
							close(sockfd);
						}
					}

					else//数据库为空
					{
						printf("database has no data\n");
					}
				}
				printf("can not get data from database\n");
			}

			else//客户端未连接服务器
			{
				if((socket_client_init(ip,port))<0)//重连失败
					{
						printf("connect to server again failure:%s\n",strerror(errno));

						if(flag==1)
						{
							if(save_data_sqlite(db,Data)<0)//保存到数据库
							{
								printf("insert data to database failure:%s\n",strerror(errno));
							}
							else
							{
								printf("insert data to database succesfully\n");
								flag=0;
							}
						}
						close(sockfd);
					}
				else//重连成功
				{
					log_info("connect to server succesfully again!\n");
				}
			}
			logger_term();
			sleep(1);
		}
	}
		close(sockfd);
		sqlite3_close( db );
		return 0;
}

int judgment_time(int interval,time_t *last_time)
{
	time_t now_time;

	time(&now_time);
	printf ("now_time=%d\n",now_time);
	if((*last_time+interval) < now_time )
	{
		printf("start to sampling\n");
		return -1;
	}

	return 0;
}

//安装信号
void sig_handle(int signum)
{
	printf("catch signal[%d]\n",signum);
	get_stop=1;
}

//参数解析
void print_usage(char *progname)
{
	printf ("%s usage:\n",progname);
	printf("-i(--ipaddr):sepcify server IP address\n");
	printf("-p(--port):sepcify server listen port.\n");
	printf ("-t(--time):sepcify report time\n");
	printf("-b(--daemon):set program runing on background\n");
	printf("-h(--help):print this help information.\n");

	return ;
}
